﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Xml;

namespace Homework2
{
    public class WebNode : INotifyPropertyChanged
    {
        private string _tag;
        private string _name;
        private string _text;
        private string _base;
        private string _url;

        /// <summary>
        /// The HTML tag name
        /// </summary>
        public string Tag
        {
            get
            {
                return _tag;
            }
            set
            {
                if (value == null || !value.Equals("#text", StringComparison.InvariantCultureIgnoreCase))
                {
                    _tag = value;
                }
                OnPropertyChanged("Tag");
            }
        }

        /// <summary>
        /// Value from a 'name' attribute, if there was one
        /// </summary>
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }

        /// <summary>
        /// Text from within the tag, if there was any
        /// </summary>
        public string Text
        {
            get { return _text; }
            set
            {
                _text = value;
                OnPropertyChanged("Text");
            }
        }

        public string Base
        {
            get { return _base; }
            set
            {
                _base = value;
                OnPropertyChanged("Base");
            }
        }

        /// <summary>
        /// Associated 'href' value, if it exists
        /// </summary>
        public string Url
        {
            get { return _url; }
            set
            {
                _url = value;
                OnPropertyChanged("Url");
            }
        }

        /// <summary>
        /// Returns a string with the WebNode's properties formatted
        /// for display in the tree
        /// </summary>
        public string DisplayText
        {
            get
            {
                var sb = new StringBuilder();

                if (_tag != null)
                {
                    sb.AppendLine("Tag: " + _tag);
                }

                if (_name != null)
                {
                    sb.AppendLine("Name: " + _name);
                }

                if (_text != null)
                {
                    sb.AppendLine((_url != null
                                       ? "Label: "
                                       : "Text: ") + _text);
                }

                if (_base != null)
                {
                    sb.AppendLine("Base: " + _base);
                }

                if (_url != null)
                {
                    sb.AppendLine("URL: " + _url);
                }

                return sb.ToString();
            }
        }

        /// <summary>
        /// The WebNode's parent WebNode
        /// </summary>
        public WebNode Parent { get; private set; }

        /// <summary>
        /// A list of child WebNodes for this node
        /// </summary>
        public List<WebNode> Children { get; private set; }

        /// <summary>
        /// This WebNode's associated XmlNode created through the HtmlAgilityPack
        /// </summary>
        public XmlNode ThisXmlNode { get; private set; }

        public WebNode(WebNode parentNode, XmlNode thisXmlNode)
        {
            Parent = parentNode;
            ThisXmlNode = thisXmlNode;
            Tag = thisXmlNode != null
                      ? thisXmlNode.Name
                      : null;
            Children = new List<WebNode>();

            if (thisXmlNode != null)
            {
                CheckAttributes();
            }
        }

        public WebNode(WebNode copy)
        {
            Parent = copy.Parent;
            ThisXmlNode = copy.ThisXmlNode;

            Tag = copy.Tag;
            Name = copy.Name;
            Base = copy.Base;
            Url = copy.Url;
            Text = copy.Text;
        }

        /// <summary>
        /// Populates certain properties of the WebNode depending on attributes found in its associated XmlNode
        /// </summary>
        private void CheckAttributes()
        {
            try
            {
                var xmlNode = ThisXmlNode;
                if (xmlNode == null || xmlNode.Attributes == null || xmlNode.Attributes.Count == 0) 
                { return; }

                var attribs = xmlNode.Attributes.Cast<XmlAttribute>();

                var url = attribs.FirstOrDefault(a => a.Name.Equals("href", StringComparison.InvariantCultureIgnoreCase));
                if (url != null)
                {
                    Url = url.Value;
                }

                var name = attribs.FirstOrDefault(a => a.Name.Equals("name", StringComparison.InvariantCultureIgnoreCase));
                if (name != null)
                {
                    Name = name.Value;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }

        #region INotifyPropertyChanged Implementation

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        } 
        
        #endregion
    }
}
